package com.wisezone.workflow.core.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.lang.StringUtils;

import com.wisezone.workflow.bean.WfActivity;
import com.wisezone.workflow.bean.WfActivityInstance;
import com.wisezone.workflow.bean.WfDataDictionary;
import com.wisezone.workflow.bean.WfProcessDefinition;
import com.wisezone.workflow.bean.WfProcessInstance;
import com.wisezone.workflow.bean.search.WfActivitySearch;
import com.wisezone.workflow.bean.search.WfProcessInstanceSearch;
import com.wisezone.workflow.core.Activity;
import com.wisezone.workflow.core.ActivityInstance;
import com.wisezone.workflow.core.FlowEngine;
import com.wisezone.workflow.core.ProcessDefinition;
import com.wisezone.workflow.core.ProcessInstance;
import com.wisezone.workflow.exception.WfCoreException;

/**
 * 流程模板对象
 * @author tss 2009-09-05
 *
 */

public class ProcessDefinitionImpl extends BasePropertyImpl implements ProcessDefinition {
	
	private WfProcessDefinition wfProcessDefinition;
	
	private List<ProcessInstance> piList;

	/**
	 * 默认构造方法
	 */
	public ProcessDefinitionImpl(){}
	
	/**
	 * 构造方法
	 * @param wfProcessDefinition 流程模板实体
	 * @param flowEngine  流程引擎对象
	 */
    public  ProcessDefinitionImpl(WfProcessDefinition wfProcessDefinition,FlowEngine flowEngine) {
    	this.wfProcessDefinition = wfProcessDefinition;
    	this.setDao(flowEngine);
    }
    
    /**
     * 加载一个活动（根据ID）
     * @param id
     * @return
     * @throws WfCoreException
     */
    public Activity loadActivityById(Long id) throws WfCoreException{

    	if(id == null){
    		throw new IllegalArgumentException("活动ID不能为空");
    	}
    	try {
    		
		   WfActivity wfActivity = this.getWfActivityDao().load(id);
		   Activity activity = new ActivityImpl(this,wfActivity);
		   return activity;
		   
		} catch (WfCoreException e) {
			e.printStackTrace();
			throw e;
		}
    }
    
    /**
     * 加载一个开始活动（根据ID）
     * @param id
     * @return
     * @throws WfCoreException
     */
    public Activity loadStartActivity() throws WfCoreException{
    	try {
    		
    		return loadActivity(getActivityCategory(ACTIVITY_DRAFT));
    		
    	} catch (WfCoreException e) {
    		e.printStackTrace();
    		throw e;
    	}
    }
    
    /**
     * 加载结束活动（根据ID）
     * @return
     * @throws WfCoreException
     */
    public Activity loadEndActivity() throws WfCoreException{
    	try {
    		
    		return loadActivity(getActivityCategory(ACTIVITY_END));
    		
    	} catch (WfCoreException e) {
    		e.printStackTrace();
    		throw e;
    	}
    }
    

    
    
    /**
     * 加载活动实例（根据ID）
     * @param id
     * @return
     * @throws WfCoreException
     */
    public ActivityInstance loadActivityInstance(Long id) throws WfCoreException{
    	
    	try {
    		WfActivityInstance wfActivityinstance = this.getWfActivityInstanceDao().load(id);
    		ProcessInstance  processInst = loadProcessInstById(wfActivityinstance.getProcessInstId());
    		ActivityInstance activityInstance = processInst.loadActivityInstById(id);
    		return activityInstance;
    		
    	} catch (WfCoreException e) {
    		e.printStackTrace();
    		throw e;
    	}
    }
    
    /**
     * 根据ID加载该流程模版的一个流程实例
     * @param id
     * @return
     * @throws WfCoreException
     */
	public ProcessInstance loadProcessInstById(Long id) throws WfCoreException{
		
		try {
		
			WfProcessInstanceSearch searchEntity = new WfProcessInstanceSearch();
			searchEntity.setId(id);			
		    return select(searchEntity);
			
		} catch (WfCoreException e) {
			e.printStackTrace();
			throw e;
		}
	}
	
    /**
     * 获得该模版下的所有流程实例
     * @return
     * @throws WfCoreException
     */
	public List<ProcessInstance> getProcessInstList() throws WfCoreException{
		
		try {
			piList = new ArrayList<ProcessInstance>();		
			WfProcessInstanceSearch entity = new WfProcessInstanceSearch();
			entity.setProcessDefId(this.wfProcessDefinition.getId());
			List<WfProcessInstance> list = this.getWfProcessInstanceDao().listAll(entity);
			
			for(Iterator<WfProcessInstance> it = list.iterator(); it.hasNext();){
				ProcessInstance processInstance = new ProcessInstanceImpl(it.next(),
						this);
				piList.add(processInstance);
			}
		} catch (WfCoreException e) {
			e.printStackTrace();
			throw e;
		}
		
		return piList;
	}
	
	/**
	 * 获得该模版下的所有流程实例(根据条件)
	 * @return
	 * @throws WfCoreException
	 */
	public List<ProcessInstance> getProcessInstList(WfProcessInstanceSearch search) throws WfCoreException{
		
		try {
			piList = new ArrayList<ProcessInstance>();	
			if(search == null){
				search = new WfProcessInstanceSearch();
			}
			search.setProcessDefId(this.wfProcessDefinition.getId());
			List<WfProcessInstance> list = this.getWfProcessInstanceDao().listAll(search);
			
			for(Iterator<WfProcessInstance> it = list.iterator(); it.hasNext();){
				ProcessInstance processInstance = new ProcessInstanceImpl(it.next(),
						this);
				piList.add(processInstance);
			}
		} catch (WfCoreException e) {
			e.printStackTrace();
			throw e;
		}
		
		return piList;
	}
	
	
	/**
	 * 加载该流程模版下的所有活动
	 * @return
	 * @throws WfCoreException
	 */
	public List<Activity> getActivityList() throws WfCoreException{
		
		WfActivitySearch searchEntity = new WfActivitySearch();
		return getActivityList(searchEntity);
	}
	
	/**
	 * 获得非开始结束活动列表
	 * @return
	 * @throws WfCoreException
	 */
	public List<Activity> getMiddleActivityList() throws WfCoreException{
		
		WfActivitySearch searchEntity = new WfActivitySearch();
		searchEntity.addSqlClause(" category != 9 and category != 10 ");
		return getActivityList(searchEntity);
	}

	
    
    /**
     * 创建一个流程实例
     * @return
     * @throws WfCoreException
     */
	public ProcessInstance createProcessInstance() throws WfCoreException{
		
		try {
			WfProcessDefinition processDefinition = getWfProcessDefinitionDao().load(wfProcessDefinition.getId());			
			WfProcessInstance pi = new WfProcessInstance();
			pi.setProcessDefId(processDefinition.getId());
			pi.setCreateTime(new Date());	
			pi.setName(wfProcessDefinition.getName());
			pi.setState(getProcessInstState(PROCESS_INST_START));               //已发起
			this.getWfProcessInstanceDao().save(pi);
			
			ProcessInstance processInstance = new ProcessInstanceImpl(pi,
					this);
			
			return processInstance;
			
		} catch (WfCoreException e) {
			e.printStackTrace();
			throw e;
		}
	}
	
	/**
	 * 激活
	 * @throws WfCoreException
	 */
	public void enabled() throws WfCoreException{
		
		WfDataDictionary dataDict = this.getWfDataDictionaryDao().load(22L);
		this.getModel().setIsActive(dataDict.getId());
		this.getWfProcessDefinitionDao().update(this.getModel());
	}

	/**
	 * 禁用
	 * @throws WfCoreException
	 */
	public void disabled() throws WfCoreException{
		
		WfDataDictionary dataDict = this.getWfDataDictionaryDao().load(23L);
		this.getModel().setIsActive(dataDict.getId());
		this.getWfProcessDefinitionDao().update(this.getModel());
	}
	
    /**
     * 获得各种类型活动
     * @param category 
     * @return activity
     * @throws WfCoreException
     */
    private Activity loadActivity(Long category) throws WfCoreException{
    	
    	if(category == null){
    		throw new IllegalArgumentException("活动类型不能为空");
    	}
    	try {
    		
			WfActivitySearch searchEntity = new WfActivitySearch();
			searchEntity.setProcessDefId(wfProcessDefinition.getId());
			searchEntity.setCategory(category);
    		WfActivity wfActivity =  this.getWfActivityDao().get(searchEntity);
    		Activity activity = new ActivityImpl(this,wfActivity);
    		return activity;
    		
    	} catch (WfCoreException e) {
    		e.printStackTrace();
    		throw e;
    	}
    }
    

	
	/**
	 * 加载该流程模版下的所有活动
	 * @param category 节点类型
	 * @return
	 * @throws WfCoreException
	 */
	private List<Activity> getActivityList(WfActivitySearch searchEntity) throws WfCoreException{
		try {
			
			searchEntity.setProcessDefId(this.wfProcessDefinition.getId());
			List<WfActivity> wfActivityList = this.getWfActivityDao().listAll(searchEntity);
			List<Activity> activityList = new ArrayList<Activity>();
			for(Iterator<WfActivity> it = wfActivityList.iterator(); it.hasNext();){
				
				Activity activity = new ActivityImpl(this,it.next());
				activityList.add(activity);  		

			}
			return activityList;
						
		} catch (WfCoreException e) {
			e.printStackTrace();
			throw e;
		}
	}
	
    /**
     * 获得流程实例
     * @param searchEntity
     * @return
     * @throws WfCoreException
     */
	private ProcessInstance select(WfProcessInstanceSearch searchEntity) throws WfCoreException{
		
		try {

			WfProcessInstance pi = null;
			if(searchEntity.getId() != null){
				pi = this.getWfProcessInstanceDao().load(searchEntity.getId());
			}else if(StringUtils.isNotEmpty(searchEntity.getName())){
				searchEntity.setProcessDefId(this.getModel().getId());
				pi =  this.getWfProcessInstanceDao().get(searchEntity);
			}
			ProcessInstance processInstance = new ProcessInstanceImpl(pi,
					this);
			processInstance.setModel(pi);
			return processInstance;
			
		} catch (WfCoreException e) {
			e.printStackTrace();
			throw e;
		}
	}


	public WfProcessDefinition getModel() {
		return wfProcessDefinition;
	}


	public void setModel(WfProcessDefinition wfProcessDefinition) {
		this.wfProcessDefinition = wfProcessDefinition;
	}


    




	
	
	
	
	
}
